package com.bsj.power.pls.netty;


import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

/**
 * netty服务器工具类
 */
@Slf4j
@Component
public class CTNettyServer {

    private ServerBootstrap bootstrap = null;
    private EventLoopGroup boss_group = null;
    private EventLoopGroup worker_group = null;

    public void start(int port) {

        bootstrap = new ServerBootstrap();
        boss_group = new NioEventLoopGroup();
        worker_group = new NioEventLoopGroup();
        bootstrap.group(boss_group, worker_group);
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new IdleStateHandler(900, 0, 0, TimeUnit.SECONDS));
                // 添加字符串解码器
                ch.pipeline().addLast(new StringDecoder());
                // 添加自定义解码器
//                ch.pipeline().addLast(new CTNettyServerHandler());
            }
        });
        bootstrap.option(ChannelOption.SO_BACKLOG, 500);
        // 准备本地绑定
        InetAddress inet_addr = null;
        try {
            inet_addr = InetAddress.getByName("0.0.0.0");
            InetSocketAddress sock_addr = new InetSocketAddress(inet_addr, port);
            bootstrap.bind(sock_addr).sync();
        } catch (Exception e) {
            if (e instanceof InterruptedException) {
                log.error("net bind err:" + port);
            } else {
                log.warn("ip err:" + port);
            }
            boss_group.shutdownGracefully();
            worker_group.shutdownGracefully();
            boss_group = null;
            worker_group = null;
            bootstrap = null;
        }
    }


    public void stop() {
        boss_group.shutdownGracefully();
        worker_group.shutdownGracefully();
        boss_group = null;
        worker_group = null;
        bootstrap = null;
    }


}
